package com.lch.base.http;

import android.content.Context;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.widget.Toast;
import com.lch.base.http.callback.ICallbackBase;
import com.lch.base.http.observer.RxObserverProgress;
import com.lch.base.http.model.params.BaseParam;
import com.lch.base.http.model.params.JsonParam;
import com.lch.base.http.utils.NetUtils;
import com.trello.rxlifecycle2.LifecycleProvider;
import java.util.Map;
import io.reactivex.Observable;
import okhttp3.MultipartBody;

/**
 * 请求构建类
 * github：https://github.com/gengqiquan/HttpUtil
 *
 * @author lee(29487113@qq.com) on 18/2/4
 */
public class HttpBuilder {
    private Context mContext;
    private ApiService mService = HttpConfig.getService();
    private ParamUtils mParamUtils;
    private String mUrl;
    private boolean mIsShowLoad; //是否显示loading框
    private ICallbackBase mCallback;

    private Map<String, String> mHeaderMap;
    private Map<String, Object> mReqMap;
    private MultipartBody mMultipartBody;
    private boolean mIsGsonPost;

    private boolean mCheckNetConnected = false; //是否需要检查网络是否连接
    private LifecycleProvider mLifecycleProvider;

    public HttpBuilder() {
        initData();
    }

    public HttpBuilder(@NonNull String url) {
        setUrl(url);
        initData();
    }

    public HttpBuilder(@NonNull String url, BaseParam baseParam) {
        setUrl(url);
        setParams(baseParam);
        initData();
    }

    private void initData() {

    }


    /**
     * 设置url
     */
    public HttpBuilder setUrl(@NonNull String url) {
        mUrl = url;
        repleceUrlParams(); //替换带参数的url
        return this;
    }

    /**
     * 设置基本请求参数-头部
     * @param baseParam get参数 post body参数的集合
     */
    public HttpBuilder setParams(BaseParam baseParam) {
        mParamUtils = new ParamUtils(baseParam);
        mHeaderMap = mParamUtils.getHeaderMap();
        mReqMap = mParamUtils.getReqMap();

        repleceUrlParams(); //替换带参数的url

        if (baseParam instanceof JsonParam) {
            mIsGsonPost = true;
        }

        return this;
    }


    /**
     * 绑定生命周期
     */
    public HttpBuilder bindToLifecycle(LifecycleProvider lifecycleProvider) {
        mLifecycleProvider = lifecycleProvider;
        return this;
    }


    /**
     * 是否显示load框
     */
    public HttpBuilder setShowLoad(boolean showLoad, Context context) {
        mIsShowLoad = showLoad;
        mContext = context;
        return this;
    }


    public HttpBuilder setCallback(ICallbackBase callback) {
        mCallback = callback;
        return this;
    }


    /**
     * 检查网络是否连接，未连接跳转到网络设置界面
     */
    public HttpBuilder setCheckNetConnected(@NonNull Context context) {
        mCheckNetConnected = true;
        mContext = context;
        return this;
    }


    /**
     * 请求前初始检查
     */
    private boolean chekcAllready() {
        // TODO: 2017/10/26 context 可以去掉
        if (mCheckNetConnected && mContext != null) {
            if (!NetUtils.isConnected(mContext)) {
                Toast.makeText(mContext, "检测到网络已关闭，请先打开网络", Toast.LENGTH_SHORT).show();
                NetUtils.openSetting(mContext);//跳转到网络设置界面
                return false;
            }
        }
        return true;
    }

    /**
     * get请求方法
     */
    public void get() {
        Observable observable = mService.get(getUrl(), mHeaderMap, mReqMap);
        handlerRequest(observable);
    }

    /**
     * 通用post，会自动根据参数类型区分post类型
     */
    public void post() {
        if (!chekcAllready()) {
            return;
        }

        mMultipartBody = mParamUtils.getMultipartBody(mCallback);
        if (mMultipartBody != null) {
            postMultipart(); //多媒体
        }

        else if (mIsGsonPost) {
            postJson();  //post-json
        }

        else {
            postForm(); //普通post
        }
    }

    public void postMultipart() {
        Observable observable = mService.postMultipart(getUrl(), mHeaderMap, mMultipartBody);
        handlerRequest(observable);
    }

    public void postJson() {
        Observable observable = mService.postJson(getUrl(), mHeaderMap, mReqMap);
        handlerRequest(observable);
    }

    public void postForm() {
        Observable observable = mService.postForm(getUrl(), mHeaderMap, mReqMap);
        handlerRequest(observable);
    }


    public <T> void handlerRequest(Observable observable) {
        if (mCallback == null) {
            mCallback = ICallbackBase.CALLBACK_DEFAULT;
        }

        observable.compose(RxTranslateUtils.<T>translate(mCallback, mLifecycleProvider))
                .subscribe(new RxObserverProgress(mCallback,mIsShowLoad, mContext));
    }





    /**
     * 获取请求url 做判断提示
     * @return
     */
    private String getUrl() {
        if (TextUtils.isEmpty(mUrl)) throw new NullPointerException("request url == null");
        return mUrl;
    }


    /**
     * 替换带参数的url
     */
    private void repleceUrlParams() {
        if (mParamUtils != null && !TextUtils.isEmpty(mUrl)) {
            mUrl = mParamUtils.genReqURL(mUrl);
        }
    }


}